/**
  ******************************************************************************
  * @file    gt32f030_vc.c
  * @author  GT Application Team
  * @version V1.0.0
  * @date    03-January-2025
  ******************************************************************************
  * @attention
  *
  * <h2><center>&copy; COPYRIGHT 2022 Giantec Semicondutor Inc</center></h2>
  *
  *             http://www.giantec-semi.com/
  *
  * Unless required by applicable law or agreed to in writing, software
  * distributed under the License is distributed on an "AS IS" BASIS,
  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  * See the License for the specific language governing permissions and
  * limitations under the License.
  *
  ******************************************************************************
  */

/* Includes ------------------------------------------------------------------*/
#include "gt32f030.h"
#include "gt32f030_rcc.h"
#include "gt32f030_vc.h"

/** @addtogroup GT32F030_StdPeriph_Driver
  * @{
  */

/* Private typedef -----------------------------------------------------------*/
/* Private define ------------------------------------------------------------*/

/* VCCMCR Register Mask */
#define VC_CMCR_CLEAR_MASK                        ((uint32_t)0x00003001)
#define VC_CR1_CLEAR_MASK                         ((uint32_t)0x07008371)
#define VC_CR2_CLEAR_MASK                         ((uint32_t)0xFFFF0001)
#define VC_CR1_FILTER_CLK_CLEAR_MASK              ((uint32_t)0x00000008)
#define VC_CR1_INT_CLEAR_MASK                     ((uint32_t)0x00001000)
#define VC_RESTORE_OUTPUT_TRIGGER(CR1)            ((uint32_t)(((CR1) & ~((uint32_t)(0x7) << 4)) |         \
                                                              ((((CR1) >> 29) & (uint32_t)(0x1)) << 6) |  \
                                                              ((((CR1) >> 29) & (uint32_t)(0x1)) << 6) |  \
                                                              ((((CR1) >> 30) & (uint32_t)(0x1)) << 5) |  \
                                                              ((((CR1) >> 31) & (uint32_t)(0x1)) << 4)))
#define VC_ENABLE                                 ((uint32_t)0x1)
#define VC_FILTER_ENABLE                          ((uint32_t)0x1)
#define VC_INT_ENABLE                             ((uint32_t)0x00001000)


/** @defgroup VC
  * @brief VC driver modules
  * @{
  */

/* Private macro -------------------------------------------------------------*/
/* Private variables ---------------------------------------------------------*/
/* Private function prototypes -----------------------------------------------*/
/* Private functions ---------------------------------------------------------*/

/** @defgroup VC_Private_Functions
  * @{
  */

/**
 * @brief  Configures the VC peripheral.
 * @param  VC_Config: pointer to a VC_ConfigTypeDef structure that contains
 *         the configuration information.
 * @retval None
 */
void VC_Config(VC_ConfigTypeDef *VC_Config) {
  /* Check the parameters */
  assert_param(IS_VC_WINDOW_MODE(VC_Config->VC_Window_Cmd));
  assert_param(IS_FUNCTIONAL_STATE(VC_Config->VC_Deglitchen_Cmd));

  VCLVD->VCCMCR &= ~VC_CMCR_CLEAR_MASK;
  VCLVD->VCCMCR |= (uint32_t)((VC_Config->VC_Window_Cmd << 12) |
                              (VC_Config->VC_Deglitchen_Cmd));
}

/**
  * @brief  Deinitializes the VC peripheral registers to their default reset values.
  * @param  None
  * @retval None
  */
void VC_DeInit(void) {
	RCC_PeriphResetCmd(RCC_PeriphReset_VCLVD, ENABLE);
	RCC_PeriphResetCmd(RCC_PeriphReset_VCLVD, DISABLE);
}

/**
  * @brief  Initializes the VC peripheral according to the specified
  *         parameters in the VC_InitStruct.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  VC_InitStruct: pointer to a VC_InitTypeDef structure that contains
  *         the configuration information.
  * @retval None
  */
void VC_Init(VCSelection_TypeDef VCx, VC_InitTypeDef *VC_InitStruct) {
  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_VC_OUTPUT_TRIGGER_MODE(VC_InitStruct->VC_Output_Trigger));
  assert_param(IS_VC_OUTPUT_POLARITY(VC_InitStruct->VC_Output_Polarity));
  assert_param(IS_VC_INPUT_PSel(VC_InitStruct->VC_Input_PSel));
  assert_param(IS_VC_INPUT_NSel(VC_InitStruct->VC_Input_NSel));
  assert_param(IS_FUNCTIONAL_STATE(VC_InitStruct->VC_Cmd));
  
  if (VCx == VC1) {
    VCLVD->VC1CR1 &= ~VC_CR1_CLEAR_MASK;
    VCLVD->VC1CR1 |= (uint32_t)((VC_InitStruct->VC_Output_Trigger << 24) |
                                (VC_InitStruct->VC_Output_Polarity << 15) |
                                (VC_InitStruct->VC_Input_PSel << 8) |
                                (VC_InitStruct->VC_Input_NSel << 4) |
                                (VC_InitStruct->VC_Cmd));
  } else if (VCx == VC2) {
    VCLVD->VC2CR1 &= ~VC_CR1_CLEAR_MASK;
    VCLVD->VC2CR1 |= (uint32_t)((VC_InitStruct->VC_Output_Trigger << 24) |
                                (VC_InitStruct->VC_Output_Polarity << 15) |
                                (VC_InitStruct->VC_Input_PSel << 8) |
                                (VC_InitStruct->VC_Input_NSel << 4) |
                                (VC_InitStruct->VC_Cmd));
  }
}

/**
  * @brief  Fills each VC_InitStruct member with its default value.
  * @param  VC_InitStruct: pointer to a VC_InitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void VC_StructInit(VC_InitTypeDef *VC_InitStruct) {
  VC_InitStruct->VC_Output_Trigger = VC_Trigger_None;
  VC_InitStruct->VC_Output_Polarity = VC_Output_Polarity_Low;
  VC_InitStruct->VC_Input_PSel = VC_Input_PSel_PB8_PB4;
  VC_InitStruct->VC_Input_NSel = VC_Input_NSel_VDDA;
  VC_InitStruct->VC_Cmd = DISABLE;
}

/**
  * @brief  Enables or disables the specified VC peripheral.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  NewState: new state of the selected VC peripheral.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void VC_Cmd(VCSelection_TypeDef VCx, FunctionalState NewState) {
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (VCx == VC1) {
    tmpreg = VCLVD->VC1CR1;  
  } else if (VCx == VC2) {
    tmpreg = VCLVD->VC2CR1;
  }

  tmpreg = VC_RESTORE_OUTPUT_TRIGGER(tmpreg);

  if (NewState != DISABLE) {
    tmpreg |= VC_ENABLE;
  } else {
    tmpreg &= ~VC_ENABLE;
  }

  if (VCx == VC1) {
    VCLVD->VC1CR1 = tmpreg;
  } else if (VCx == VC2) {
    VCLVD->VC2CR1 = tmpreg;
  }
}

/**
  * @brief  Initializes the VC Filter peripheral according to the specified
  *         parameters in the VC_FilterInitStruct.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  VC_FilterInitStruct: pointer to a VC_FilterInitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void VC_FilterInit(VCSelection_TypeDef VCx, VC_FilterInitTypeDef *VC_FilterInitStruct) {
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_VC_FILTER_CLOCK(VC_FilterInitStruct->VCFilter_ClockSource));
  assert_param(IS_VC_FILTER_NUMBER(VC_FilterInitStruct->VCFilter_Number));
  assert_param(IS_VC_FILTER_OUTPUT_GATE(VC_FilterInitStruct->VCFilter_Output));
  assert_param(IS_FUNCTIONAL_STATE(VC_FilterInitStruct->VCFilter_Cmd));

  if (VCx == VC1) {
    tmpreg = VCLVD->VC1CR1;  
  } else if (VCx == VC2) {
    tmpreg = VCLVD->VC2CR1;
  }

  tmpreg = VC_RESTORE_OUTPUT_TRIGGER(tmpreg);

  tmpreg &= ~VC_CR1_FILTER_CLK_CLEAR_MASK;
  tmpreg |= (uint32_t)((VC_FilterInitStruct->VCFilter_ClockSource << 3));

  if (VCx == VC1) {
    VCLVD->VC1CR1 = tmpreg;
    VCLVD->VC1CR2 &= ~VC_CR2_CLEAR_MASK;
    VCLVD->VC1CR2 |= (uint32_t)(((uint32_t)(VC_FilterInitStruct->VCFilter_Number << 16)) |
                                (VC_FilterInitStruct->VCFilter_Cmd));
    VCLVD->VC1OCR2 = (uint32_t)(VC_FilterInitStruct->VCFilter_Output);
  } else if (VCx == VC2) {
    VCLVD->VC2CR1 = tmpreg;
    VCLVD->VC2CR2 &= ~VC_CR2_CLEAR_MASK;
    VCLVD->VC2CR2 |= (uint32_t)(((uint32_t)(VC_FilterInitStruct->VCFilter_Number << 16)) |
                                (VC_FilterInitStruct->VCFilter_Cmd));
    VCLVD->VC2OCR2 = (uint32_t)(VC_FilterInitStruct->VCFilter_Output);
  }
}

/**
  * @brief  Fills each VC_FilterInitStruct member with its default value.
  * @param  VC_FilterInitStruct: pointer to a VC_FilterInitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void VC_FilterStructInit(VC_FilterInitTypeDef *VC_FilterInitStruct) {
  VC_FilterInitStruct->VCFilter_ClockSource = VC_Filter_Clock_PCLK;
  VC_FilterInitStruct->VCFilter_Number = 0;
  VC_FilterInitStruct->VCFilter_Output = 0;
  VC_FilterInitStruct->VCFilter_Cmd = DISABLE;
}

/**
  * @brief  Enables or disables the specified VC Filter peripheral.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  NewState: new state of the selected VC Filter peripheral.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void VC_FilterCmd(VCSelection_TypeDef VCx, FunctionalState NewState) {
  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (VCx == VC1) {
    if (NewState != DISABLE) {
      VCLVD->VC1CR2 |= VC_FILTER_ENABLE;
    } else {
      VCLVD->VC1CR2 &= ~VC_FILTER_ENABLE;
    }
  } else if (VCx == VC2) {
    if (NewState != DISABLE) {
      VCLVD->VC2CR2 |= VC_FILTER_ENABLE;
    } else {
      VCLVD->VC2CR2 &= ~VC_FILTER_ENABLE;
    }
  }
}

/**
  * @brief  Initializes the VC Interrupt peripheral according to the specified
  *         parameters in the VC_IntInitStruct.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  VC_IntInitStruct: pointer to a VC_IntInitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void VC_IntInit(VCSelection_TypeDef VCx, VC_IntInitTypeDef *VC_IntInitStruct) {
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_VC_INT_OUTPUT_BRAKE(VC_IntInitStruct->VCInt_Output));
  assert_param(IS_FUNCTIONAL_STATE(VC_IntInitStruct->VCInt_Cmd));

  if (VCx == VC1) {
    tmpreg = VCLVD->VC1CR1;  
  } else if (VCx == VC2) {
    tmpreg = VCLVD->VC2CR1;
  }

  tmpreg = VC_RESTORE_OUTPUT_TRIGGER(tmpreg);

  tmpreg &= ~VC_CR1_INT_CLEAR_MASK;

  if (VC_IntInitStruct->VCInt_Cmd != DISABLE) {
    tmpreg |= VC_INT_ENABLE;
  } else {
    tmpreg &= ~VC_INT_ENABLE;
  }

  if (VCx == VC1) {
    VCLVD->VC1CR1 = tmpreg;
    VCLVD->VC1OCR1 = (uint32_t)(VC_IntInitStruct->VCInt_Output);
  } else if (VCx == VC2) {
    VCLVD->VC2CR1 = tmpreg;
    VCLVD->VC2OCR1 = (uint32_t)(VC_IntInitStruct->VCInt_Output);
  }
}

/**
  * @brief  Fills each VC_IntInitStruct member with its default value.
  * @param  VC_IntInitStruct: pointer to a VC_IntInitTypeDef structure
  *         which will be initialized.
  * @retval None
  */
void VC_IntStructInit(VC_IntInitTypeDef *VC_IntInitStruct) {
  VC_IntInitStruct->VCInt_Output = 0;
  VC_IntInitStruct->VCInt_Cmd = DISABLE;
}

/**
  * @brief  Enables or disables the specified VC Interrupt peripheral.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @param  NewState: new state of the selected VC Interrupt peripheral.
  *         This parameter can be: ENABLE or DISABLE.
  * @retval None
  */
void VC_ITConfig(VCSelection_TypeDef VCx, FunctionalState NewState) {
  uint32_t tmpreg = 0;

  /* Check the parameters */
  assert_param(IS_VC_ALL_PERIPH(VCx));
  assert_param(IS_FUNCTIONAL_STATE(NewState));

  if (VCx == VC1) {
    tmpreg = VCLVD->VC1CR1;  
  } else if (VCx == VC2) {
    tmpreg = VCLVD->VC2CR1;
  }

  tmpreg = VC_RESTORE_OUTPUT_TRIGGER(tmpreg);

  if (NewState != DISABLE) {
    tmpreg |= VC_INT_ENABLE;
  } else {
    tmpreg &= ~VC_INT_ENABLE;
  }

  if (VCx == VC1) {
    VCLVD->VC1CR1 = tmpreg;
  } else if (VCx == VC2) {
    VCLVD->VC2CR1 = tmpreg;
  }
}

/**
  * @brief  Clears the VC Interrupt.
  * @param  VCx: selects the VC peripheral. This parameter can be one of
  *         the following values: VC1 or VC2.
  * @retval None
  */
void VC_ClearIT(VCSelection_TypeDef VCx) {
  if (VCx == VC1) {
    VCLVD->ISR = 0x19d00001;
  } else if (VCx == VC2) {
    VCLVD->ISR = 0x19d00002;
  }
}

/**
  * @}
  */

/**
  * @}
  */

/**
  * @}
  */

/************************ (C) COPYRIGHT Giantec Semicondutor Inc *****END OF FILE****/
